package models

import (
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

// Command represents a command sent to a device
type Command struct {
	ID          uuid.UUID       `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	DeviceID    uuid.UUID       `json:"device_id" gorm:"type:uuid;not null"`
	Device      Device          `json:"device" gorm:"foreignKey:DeviceID"`
	UserID      *uuid.UUID      `json:"user_id" gorm:"type:uuid"`
	User        *User           `json:"user" gorm:"foreignKey:UserID"`
	Name        string          `json:"name" gorm:"not null"`
	Payload     CommandPayload  `json:"payload" gorm:"type:jsonb"`
	Status      CommandStatus   `json:"status" gorm:"default:pending"`
	Priority    CommandPriority `json:"priority" gorm:"default:normal"`
	ExpiresAt   *time.Time      `json:"expires_at"`
	SentAt      *time.Time      `json:"sent_at"`
	AckedAt     *time.Time      `json:"acked_at"`
	CompletedAt *time.Time      `json:"completed_at"`
	Response    CommandResponse `json:"response" gorm:"type:jsonb"`
	Retries     int             `json:"retries" gorm:"default:0"`
	MaxRetries  int             `json:"max_retries" gorm:"default:3"`
	CreatedAt   time.Time       `json:"created_at"`
	UpdatedAt   time.Time       `json:"updated_at"`
	DeletedAt   gorm.DeletedAt  `json:"deleted_at" gorm:"index"`
}

type CommandStatus string

const (
	CommandStatusPending   CommandStatus = "pending"
	CommandStatusSent      CommandStatus = "sent"
	CommandStatusAcked     CommandStatus = "acknowledged"
	CommandStatusCompleted CommandStatus = "completed"
	CommandStatusFailed    CommandStatus = "failed"
	CommandStatusExpired   CommandStatus = "expired"
	CommandStatusCanceled  CommandStatus = "canceled"
)

type CommandPriority string

const (
	CommandPriorityLow      CommandPriority = "low"
	CommandPriorityNormal   CommandPriority = "normal"
	CommandPriorityHigh     CommandPriority = "high"
	CommandPriorityCritical CommandPriority = "critical"
)

type CommandPayload struct {
	Method     string                 `json:"method"`
	Parameters map[string]interface{} `json:"parameters"`
	Options    map[string]interface{} `json:"options"`
}

type CommandResponse struct {
	Status    string                 `json:"status"`
	Message   string                 `json:"message"`
	Data      map[string]interface{} `json:"data"`
	Error     string                 `json:"error,omitempty"`
	Timestamp time.Time              `json:"timestamp"`
}

// Rule represents a business rule for data processing
type Rule struct {
	ID             uuid.UUID      `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	Name           string         `json:"name" gorm:"not null"`
	Description    string         `json:"description"`
	Type           RuleType       `json:"type" gorm:"not null"`
	Status         RuleStatus     `json:"status" gorm:"default:active"`
	Priority       int            `json:"priority" gorm:"default:100"`
	Conditions     RuleConditions `json:"conditions" gorm:"type:jsonb"`
	Actions        RuleActions    `json:"actions" gorm:"type:jsonb"`
	DeviceIDs      []uuid.UUID    `json:"device_ids" gorm:"type:uuid[]"`
	Tags           []string       `json:"tags" gorm:"type:text[]"`
	OwnerID        uuid.UUID      `json:"owner_id" gorm:"type:uuid;not null"`
	Owner          User           `json:"owner" gorm:"foreignKey:OwnerID"`
	ExecutionCount int64          `json:"execution_count" gorm:"default:0"`
	LastExecuted   *time.Time     `json:"last_executed"`
	CreatedAt      time.Time      `json:"created_at"`
	UpdatedAt      time.Time      `json:"updated_at"`
	DeletedAt      gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}

type RuleType string

const (
	RuleTypeThreshold RuleType = "threshold"
	RuleTypeSchedule  RuleType = "schedule"
	RuleTypeAnomaly   RuleType = "anomaly"
	RuleTypeSequence  RuleType = "sequence"
	RuleTypeGeofence  RuleType = "geofence"
)

type RuleStatus string

const (
	RuleStatusActive   RuleStatus = "active"
	RuleStatusInactive RuleStatus = "inactive"
	RuleStatusPaused   RuleStatus = "paused"
	RuleStatusError    RuleStatus = "error"
)

type RuleConditions struct {
	Expression string                 `json:"expression"` // SQL-like expression
	Filters    []RuleFilter           `json:"filters"`
	TimeWindow string                 `json:"time_window"`
	Options    map[string]interface{} `json:"options"`
}

type RuleFilter struct {
	Field    string      `json:"field"`
	Operator string      `json:"operator"` // "eq", "ne", "gt", "lt", "gte", "lte", "in", "nin"
	Value    interface{} `json:"value"`
	Type     string      `json:"type"` // "string", "number", "boolean", "array"
}

type RuleActions struct {
	Actions []RuleAction `json:"actions"`
}

type RuleAction struct {
	Type       string                 `json:"type"` // "alert", "command", "webhook", "email", "sms"
	Target     string                 `json:"target"`
	Parameters map[string]interface{} `json:"parameters"`
	Enabled    bool                   `json:"enabled"`
}

// Webhook represents an external webhook endpoint
type Webhook struct {
	ID        uuid.UUID      `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	Name      string         `json:"name" gorm:"not null"`
	URL       string         `json:"url" gorm:"not null"`
	Method    string         `json:"method" gorm:"default:POST"`
	Headers   WebhookHeaders `json:"headers" gorm:"type:jsonb"`
	Secret    string         `json:"-"` // Hidden in JSON
	Enabled   bool           `json:"enabled" gorm:"default:true"`
	Retries   int            `json:"retries" gorm:"default:3"`
	Timeout   int            `json:"timeout" gorm:"default:30"` // seconds
	OwnerID   uuid.UUID      `json:"owner_id" gorm:"type:uuid;not null"`
	Owner     User           `json:"owner" gorm:"foreignKey:OwnerID"`
	CreatedAt time.Time      `json:"created_at"`
	UpdatedAt time.Time      `json:"updated_at"`
	DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}

type WebhookHeaders map[string]string

// WebhookLog represents webhook execution logs
type WebhookLog struct {
	ID           uuid.UUID `json:"id" gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
	WebhookID    uuid.UUID `json:"webhook_id" gorm:"type:uuid;not null"`
	Webhook      Webhook   `json:"webhook" gorm:"foreignKey:WebhookID"`
	RequestBody  string    `json:"request_body"`
	ResponseCode int       `json:"response_code"`
	ResponseBody string    `json:"response_body"`
	Error        string    `json:"error"`
	Duration     int64     `json:"duration"` // milliseconds
	Success      bool      `json:"success"`
	CreatedAt    time.Time `json:"created_at"`
}
